﻿using FySystem.Extension;
using FySystem.Net.SimSocket;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FyCacheClient
{
    internal class CommandExecuter
    {
        private ManualResetEvent _allDone = new ManualResetEvent(false);
        internal FrameInfo Frame { get; set; }

        /// <summary>
        /// 将异步转为同步
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal CommandResponse Execute(SimClient simClient, List<byte> data, ushort timeout)
        {
            CommandResponse res = new CommandResponse();
            try
            {
                simClient.OnReceive = (simClient, frame) =>
                  {
                      Frame = frame;
                      Continue();
                  };

                _allDone.Reset();
                simClient.Send(data);
                _allDone.WaitOne(timeout * 1000);

                //阻塞等待
                if (Frame != null)
                {
                    if (Frame.Frame[16] == 0x00)
                    {
                        //如果服务端没报错
                        res.Command = new byte[2];
                        res.Command[0] = data[17];
                        res.Command[1] = data[18];
                        res.Data = Frame.Frame.ReadBytes(19);
                    }
                    else
                    {
                        //如果服务端报错了
                        int code = BitConverter.ToInt32(Frame.Frame, 17);
                        string err = Encoding.UTF8.GetString(Frame.Frame, 21, Frame.Frame.Length - 21);
                        throw new Exception($"{code}#{err}");
                    }
                }
                else
                    throw new Exception("连接超时~");
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 表示收到数据了，继续后续逻辑
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        internal void Continue()
        {
            try
            {
                _allDone.Set();
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
